/**
 *Copyright (c) 2017- https://gitee.com/allmx/master.git
 * hhqk-lmx:下午2:20:02
 */
package org.hhqk.admin.mockito.test;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

import java.util.LinkedList;
import java.util.List;

import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

/**
 * @author Administrator
 * BaseMockitoTest2.java
 * 2017年12月7日
 * <p>description:使用注解的模式
 * 	1.@Mock 模拟一个对象；
 *  2.在构造器中进行初始化 MockitoAnnotations.initMocks(this)/@RunWith(MockitoJUnitRunner.class)
 * </p>
 */
public class BaseMockitoTest2 {
	@SuppressWarnings("rawtypes")
	@Mock  
	private List mockList;
	
	public BaseMockitoTest2(){
		MockitoAnnotations.initMocks(this);
	}
	
	@SuppressWarnings("unchecked")
	@Test  
	public void shorthand(){  
	    mockList.add(1);  
	    verify(mockList).add(1);  
	} 
	
	@Test(expected = IndexOutOfBoundsException.class)  
	public void spy_on_real_objects(){  
	    List list = new LinkedList();  
	    List spy = spy(list);  
	    //下面预设的spy.get(0)会报错，因为会调用真实对象的get(0)，所以会抛出越界异常  
	    //when(spy.get(0)).thenReturn(3);  
	  
	    //使用doReturn-when可以避免when-thenReturn调用真实对象api  
	    doReturn(999).when(spy).get(999);  
	    //预设size()期望值  
	    when(spy.size()).thenReturn(100);  
	    //调用真实对象的api  
	    spy.add(1);  
	    spy.add(2);  
	    assertEquals(100,spy.size());  
	    assertEquals(1,spy.get(0));  
	    assertEquals(2,spy.get(1));  
	    verify(spy).add(1);  
	    verify(spy).add(2);  
	    assertEquals(999,spy.get(999));  
	    spy.get(2);  
	}  
	
	/*
	 * 捕获参数来进一步断言
	 */
	  @Test  
	  public void capturing_args(){  
	      PersonDao personDao = mock(PersonDao.class);  
	      PersonService personService = new PersonService(personDao);  
	    
	      ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);  
	      personService.update(1,"jack");  
	      verify(personDao).update(argument.capture());  
	      assertEquals(1,argument.getValue().getId());  
	      assertEquals("jack",argument.getValue().getName());  
	  }  
	  
	   class Person{  
	      private int id;  
	      private String name;  
	    
	      Person(int id, String name) {  
	          this.id = id;  
	          this.name = name;  
	      }  
	    
	      public int getId() {  
	          return id;  
	      }  
	    
	      public String getName() {  
	          return name;  
	      }  
	  }  
	    
	  interface PersonDao{  
	      public void update(Person person);  
	  }  
	    
	  class PersonService{  
	      private PersonDao personDao;  
	    
	      PersonService(PersonDao personDao) {  
	          this.personDao = personDao;  
	      }  
	    
	      public void update(int id,String name){  
	          personDao.update(new Person(id,name));  
	      }  
	  }  
}
